package net.dgg.rz.production.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import net.dgg.framework.tac.utils.DggValidateUtil;
import net.dgg.framework.tac.utils.idutil.DggKeyWorker;
import net.dgg.iboss.base.service.CmsService;
import net.dgg.iboss.base.service.OrfApiService;
import net.dgg.iboss.base.util.DesUtil;
import net.dgg.rz.api.production.service.RecognitionService;
import net.dgg.rz.common.base.service.BaseService;
import net.dgg.rz.common.constant.ModuleCodeConstant;
import net.dgg.rz.common.constant.ScNoteType;
import net.dgg.rz.common.constant.ScProductConstant;
import net.dgg.rz.common.entity.CustomerRecord;
import net.dgg.rz.common.excption.CommonExcption;
import net.dgg.rz.common.service.CommonService;
import net.dgg.rz.common.systemRecord.service.SystemRecordService;
import net.dgg.rz.common.utils.*;
import net.dgg.rz.production.dao.*;
import net.dgg.rz.production.entity.*;
import net.dgg.rz.production.entity.dto.ProductOrderDto;
import net.dgg.rz.production.exception.FlowNodeExcption;
import net.dgg.rz.production.exception.ProductOrderExcption;
import net.dgg.tmd.foundation.platform.org.entity.OrganizationEntity;
import net.dgg.tmd.foundation.platform.org.service.OrganizationManager;
import net.dgg.tmd.foundation.platform.session.SessionManager;
import net.dgg.tmd.foundation.platform.user.entity.UserEntity;
import net.dgg.tmd.foundation.platform.user.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * 节点管理 service层
 * Created by cuipeng on 2018/12/14.
 **/
@Service
public class FlowNodeService extends BaseService {


    protected Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private ProductNodeFlowDao productNodeFlowDao;

    @Autowired
    private SessionManager sessionManager;

    @Autowired
    private CmsService cmsService;

    @Autowired
    private ProductNodeDao productNodeDao;

    @Autowired
    private ProductNodeFieldDao productNodeFieldDao;

    @Autowired
    private ProductOrderDao productOrderDao;//主订单dao
    @Autowired
    private AssistantDao assistantDao;//查询协办人service
    @Autowired
    private OrganizationManager organizationManager ;//查询所在部门service
    @Autowired
    private SystemRecordService systemRecordService;//日志service
    @Autowired
    protected UserService userservice;//用户service
    @Autowired
    protected ProductNodeOperatingDao productNodeOperatingDao;//流程记录service
    @Autowired
    private ProductOrderService productOrderService;//主订单service
    @Autowired
    private ProductTimeStatusDao productTimeStatusDao;//超期表
    @Resource
    private CommonService commonService;
    @Autowired
    private OrfApiService orfApiService;
    @Autowired
    private ProductTimeStatusService productTimeStatusService;
    @Autowired
    private RecognitionService recognitionService;
    @Autowired
    private SearchUtils searchUtils;
    @Autowired
    PunishDetailDao punishDetailDao;
    @Autowired
    NodeTimeOutPunishDao nodeTimeOutPunishDao;

    @Autowired
    private DesUtil desUtil;
    /**
     * 根据条件搜索用户DTO并返回
     *
     * @param map
     * @return
     */
    @Transactional(readOnly = true)
    public List<ProductNodeFlow> findAllFlowWithPage(Map map) {
        UserEntity userEntity = sessionManager.getCurrentUser();
        ValidateUtils.strNotEmpty(userEntity, ProductOrderExcption.class, "未获取到登陆人，请重新登录！");
        List<ProductNodeFlow> productNodeFlowList = productNodeFlowDao.queryWithPage(map);
        return productNodeFlowList;
    }

    /**
     * @Title:新增或者保存流程信息(老)老的流程是通过事业部ID+业态验证是否唯一
     * @author: cuipeng
     * @creat_date: 2018/12/14
     **/
    @Transactional
    @SuppressWarnings("all")
    public void saveFlow(Map params) {
        UserEntity sessionUser = this.sessionManager.getCurrentUser();
        ValidateUtils.strNotEmpty(sessionUser, ProductOrderExcption.class, "未获取到登陆人，请重新登录！");
        ProductNodeFlow flow = new ProductNodeFlow();
        if (StringUtils.isNotEmpty(params.get("flowId"))) {
            Map tjmap = new HashMap();
            tjmap.put("flowId", String.valueOf(params.get("flowId")));
            tjmap.put("flag", 1);
            flow = productNodeFlowDao.queryFlowById(tjmap);
        }
        flow.setDeptIds(Long.parseLong(String.valueOf(params.get("orgId"))));
        String buscode = "";
        if (null == params.get("typeCodeAdd")) {//getOrgNameById()
            buscode = String.valueOf(params.get("typeCodeEdit"));
            //flow.setDeptNames(String.valueOf(params.get("selectTreeAddressIdEdit")));
        } else {
            buscode = String.valueOf(params.get("typeCodeAdd"));
            //flow.setDeptNames(String.valueOf(params.get("selectTreeAddRessId")));
        }
        flow.setDeptNames(getOrgNameById(Long.parseLong(String.valueOf(params.get("orgId")))));
        Map busCodeMap = cmsService.getTreeBookObj(buscode);
        Map BigFormatCodeMap = cmsService.getTreeBookObj(String.valueOf(busCodeMap.get("pcode")));


        flow.setBusinessName(String.valueOf(busCodeMap.get("name")));
        flow.setManagementCycle(Integer.parseInt(String.valueOf(params.get("blDate"))));
        flow.setIsnaturalorworkday(Integer.parseInt(String.valueOf(params.get("isnaturalorworkday"))));
        flow.setExamineGrade(Integer.parseInt(String.valueOf(params.get("examinGrade"))));

        List<Map> ue = new ArrayList<>();
        String buslevel = String.valueOf(busCodeMap.get("levels"));
        int num = appearNumber(buslevel, "_");
        if (num == 3) {
            flow.setBigformatCode(String.valueOf(busCodeMap.get("code")));
            flow.setBigformatName(String.valueOf(busCodeMap.get("name")));
            flow.setBusinessCode(null);
            flow.setBusinessName(null);
            ue = productNodeFlowDao.findFlowEntityByBigFormatCode(flow);
        } else if (num == 4) {
            flow.setBigformatCode(String.valueOf(BigFormatCodeMap.get("code")));
            flow.setBigformatName(String.valueOf(BigFormatCodeMap.get("name")));
            flow.setBusinessCode(String.valueOf(busCodeMap.get("code")));
            flow.setBusinessName(String.valueOf(busCodeMap.get("name")));
            ue = productNodeFlowDao.findFlowEntityByBusiness(flow);
        } else {
            throw new CommonExcption("业态类型出现异常！");
        }
        if (ue.size() > 0) {
            throw new CommonExcption("保存失败，该业态流程已存在！");
        }
        if (flow.getId() == null) {// 新增
            long id = DggKeyWorker.nextId();
            flow.setId(id);
            String number = cmsService.getBillNumber("LC");
            ValidateUtils.isTrue(StringUtils.isNotEmpty(number), CommonExcption.class, "单据号获取失败,请联系管理员");
            flow.setFlowNo(number);
            flow.setFlag(1);
            flow.setIsOld(0);
            this.saveOpt(flow, sessionUser);
            productNodeFlowDao.save(flow);

            ProductNode jdnode = new ProductNode();
            jdnode.setId(DggKeyWorker.nextId());
            jdnode.setName("接单");
            jdnode.setHandleDate(1);
            jdnode.setIsNaturalorWorkday(1);
            jdnode.setIsKey(1);
            jdnode.setSort(1);
            jdnode.setProcessId(id);
            jdnode.setFlag(1);
            this.saveOpt(jdnode, sessionUser);

            ProductNode fknode = new ProductNode();
            fknode.setId(DggKeyWorker.nextId());
            fknode.setName("放款");
            fknode.setHandleDate(1);
            fknode.setIsNaturalorWorkday(1);
            fknode.setIsKey(1);
            fknode.setSort(2);
            fknode.setProcessId(id);
            fknode.setFlag(1);
            this.saveOpt(jdnode, sessionUser);

            /*ProductNode qzwjnode = new ProductNode();
            qzwjnode.setId(DggKeyWorker.nextId());
            qzwjnode.setName("强制完结");
            qzwjnode.setHandleDate(1);
            qzwjnode.setIsNaturalorWorkday(1);
            qzwjnode.setIsKey(1);
            qzwjnode.setSort(3);
            qzwjnode.setProcessId(id);
            qzwjnode.setFlag(1);
            this.saveOpt(qzwjnode, sessionUser);*/

            ProductNode wjnode = new ProductNode();
            wjnode.setId(DggKeyWorker.nextId());
            wjnode.setName("完结");
            wjnode.setHandleDate(1);
            wjnode.setIsNaturalorWorkday(1);
            wjnode.setIsKey(1);
            wjnode.setSort(3);
            wjnode.setProcessId(id);
            wjnode.setFlag(1);
            this.saveOpt(wjnode, sessionUser);

            productNodeDao.save(jdnode);
            productNodeDao.save(fknode);
            /*productNodeDao.save(qzwjnode);*/
            productNodeDao.save(wjnode);
        } else {
            this.updateOpt(flow, sessionUser);
            productNodeFlowDao.update(flow);
        }
    }

    /**
     * @Title:新增或者保存流程信息(新)新的流程是通过商品+渠道判断流程是否存在
     * @author: cuipeng
     * @creat_date: 2018/12/14
     **/
    @Transactional
    @SuppressWarnings("all")
    public void saveFlowNew(Map params) {
        UserEntity sessionUser = this.sessionManager.getCurrentUser();
        ValidateUtils.strNotEmpty(sessionUser, ProductOrderExcption.class, "未获取到登陆人，请重新登录！");
        ValidateUtils.strNotEmpty(params.get("productId"), ProductOrderExcption.class, "产品ID不能为空！");
        //ValidateUtils.strNotEmpty(params.get("productName"), ProductOrderExcption.class, "产品名字不能为空！");
        //ValidateUtils.strNotEmpty(params.get("goodsId"), ProductOrderExcption.class, "商品ID不能为空！");
        //ValidateUtils.strNotEmpty(params.get("goodsName"), ProductOrderExcption.class, "商品名字不能为空！");
        //ValidateUtils.strNotEmpty(params.get("channelId"), ProductOrderExcption.class, "渠道ID不能为空！");
        //ValidateUtils.strNotEmpty(params.get("channelName"), ProductOrderExcption.class, "渠道名字不能为空！");
        ValidateUtils.strNotEmpty(params.get("blDate"), ProductOrderExcption.class, "办理周期不能为空！");
        ValidateUtils.strNotEmpty(params.get("isnaturalorworkday"), ProductOrderExcption.class, "是否工作日不能为空！");
        ValidateUtils.strNotEmpty(params.get("examinGrade"), ProductOrderExcption.class, "审核登记不能为空！");

        ProductNodeFlow flow = new ProductNodeFlow();
        if (StringUtils.isNotEmpty(params.get("flowId"))) {
            Map tjmap = new HashMap();
            tjmap.put("flowId", String.valueOf(params.get("flowId")));
            tjmap.put("flag", 1);
            flow = productNodeFlowDao.queryFlowById(tjmap);
        }

        Long productId = Long.parseLong(params.get("productId").toString());
        //换取产品中心id
        productId = commonService.getSerialId(productId);
        flow.setProductId(productId);
        //根据产品ID查询产品名字
        flow.setProductName(getProductNameByProductId(Long.parseLong(params.get("productId").toString())));

        String buscode = "";
        if (null == params.get("typeCodeAdd")) {
            buscode = String.valueOf(params.get("typeCodeEdit"));
        } else {
            buscode = String.valueOf(params.get("typeCodeAdd"));
        }
        Map busCodeMap = cmsService.getTreeBookObj(buscode);
        Map BigFormatCodeMap = cmsService.getTreeBookObj(String.valueOf(busCodeMap.get("pcode")));

        flow.setBusinessName(String.valueOf(busCodeMap.get("name")));
        flow.setManagementCycle(Integer.parseInt(String.valueOf(params.get("blDate"))));
        flow.setIsnaturalorworkday(Integer.parseInt(String.valueOf(params.get("isnaturalorworkday"))));
        flow.setExamineGrade(Integer.parseInt(String.valueOf(params.get("examinGrade"))));

        String buslevel = String.valueOf(busCodeMap.get("levels"));
        int num = appearNumber(buslevel, "_");
        int count = 0;
        if (num == 3) {
            flow.setBigformatCode(String.valueOf(busCodeMap.get("code")));
            flow.setBigformatName(String.valueOf(busCodeMap.get("name")));
            flow.setBusinessCode(null);
            flow.setBusinessName(null);
            count = productNodeFlowDao.countByBigBusinessCodeAndProductId(flow);
        } else if (num == 4) {
            flow.setBigformatCode(String.valueOf(BigFormatCodeMap.get("code")));
            flow.setBigformatName(String.valueOf(BigFormatCodeMap.get("name")));
            flow.setBusinessCode(String.valueOf(busCodeMap.get("code")));
            flow.setBusinessName(String.valueOf(busCodeMap.get("name")));
            count = productNodeFlowDao.countByBusinessCodeAndProductId(flow);
        } else {
            throw new CommonExcption("业态类型出现异常！");
        }

        //int count = productNodeFlowDao.countByChannelAndGoods(flow);//tt
        if (count>0) {
            throw new CommonExcption("保存失败，流程已存在！");
        }
        if (flow.getId() == null) {// 新增
            long id = DggKeyWorker.nextId();
            flow.setId(id);
            String number = cmsService.getBillNumber("LC");
            ValidateUtils.isTrue(StringUtils.isNotEmpty(number), CommonExcption.class, "单据号获取失败,请联系管理员");
            flow.setFlowNo(number);
            flow.setFlag(1);
            flow.setIsOld(1);
            this.saveOpt(flow, sessionUser);
            productNodeFlowDao.save(flow);

            ProductNode jdnode = new ProductNode();
            jdnode.setId(DggKeyWorker.nextId());
            jdnode.setName("接单");
            jdnode.setHandleDate(1);
            jdnode.setIsNaturalorWorkday(1);
            jdnode.setIsKey(1);
            jdnode.setIsPunish(2);//是否扣罚
            jdnode.setIsWarning(2);//是否预警
            jdnode.setSort(1);
            jdnode.setProcessId(id);
            jdnode.setFlag(1);
            jdnode.setVersion(0L);
            this.saveOpt(jdnode, sessionUser);

            ProductNode fknode = new ProductNode();
            fknode.setId(DggKeyWorker.nextId());
            fknode.setName("放款");
            fknode.setHandleDate(1);
            fknode.setIsNaturalorWorkday(1);
            fknode.setIsKey(1);
            fknode.setIsPunish(2);//是否扣罚
            fknode.setIsWarning(2);//是否预警
            fknode.setSort(2);
            fknode.setProcessId(id);
            fknode.setFlag(1);
            fknode.setVersion(0L);
            this.saveOpt(jdnode, sessionUser);


            ProductNode wjnode = new ProductNode();
            wjnode.setId(DggKeyWorker.nextId());
            wjnode.setName("完结");
            wjnode.setHandleDate(1);
            wjnode.setIsNaturalorWorkday(1);
            wjnode.setIsKey(1);//是否关键节点
            wjnode.setIsPunish(2);//是否扣罚
            wjnode.setIsWarning(2);//是否预警
            wjnode.setSort(3);
            wjnode.setProcessId(id);
            wjnode.setFlag(1);
            wjnode.setVersion(0L);
            this.saveOpt(wjnode, sessionUser);

            productNodeDao.save(jdnode);
            productNodeDao.save(fknode);
            productNodeDao.save(wjnode);
        } else {
            this.updateOpt(flow, sessionUser);
            productNodeFlowDao.update(flow);
        }
    }

    /**
     * @Title:根据flowID获取流程信息
     * @author: cuipeng
     * @creat_date: 2018/12/14
     **/
    public ProductNodeFlow findFlowById(Map map) {
        ValidateUtils.strNotEmpty(map.get("flowId"), ProductOrderExcption.class, "流程ID传入失败！");
        ProductNodeFlow rzFlow = productNodeFlowDao.queryFlowById(map);
        ValidateUtils.strNotEmpty(rzFlow, FlowNodeExcption.class, "未查询到对应的流程");
        ValidateUtils.strNotEmpty(rzFlow.getExamineGrade(), FlowNodeExcption.class, "未查询到对应的流程的审核级数");
        return rzFlow;
    }

    /**
     * @Title:根据事业部ID获取关键字段信息
     * @author: cuipeng
     * @creat_date: 2018/12/14
     **/
    public List<ProductNodeField> findNodefield(Map map) {
        List<ProductNodeField> sc_NodeFieldList = productNodeFieldDao.query(map);
        return sc_NodeFieldList;
    }

    /**
     * @Title:根据flowId获取除接单、完结外的节点信息list
     * @author: cuipeng
     * @creat_date: 2018/12/14
     **/
    public List<ProductNode> findNodeCenterById(Map map) {
        ValidateUtils.strNotEmpty(map.get("flowId"), ProductOrderExcption.class, "流程ID传入失败");
        List<ProductNode> sc_NodeList = productNodeDao.queryNodeCenter(map);
        return sc_NodeList;
    }

    /**
     * @Title:根据flowId获取接单节点信息ScProductNode
     * @author: cuipeng
     * @creat_date: 2018/12/14
     **/

    public ProductNode findNodeJdById(Map map, List<ProductNode> sc_NodeList) {
        ValidateUtils.strNotEmpty(map.get("flowId"), ProductOrderExcption.class, "流程ID传入失败！");
        ProductNode nodeJd = productNodeDao.queryNodeJd(map);
        //Assert.notNull(nodeJd, "接单节点出现异常，请联系管理员！");
        /*if (sc_NodeList == null && nodeJd != null) {
            throw new CommonExcption("流程出现异常，请联系管理员！");
        }*/
        return nodeJd;
    }

    /**
     * @Title:根据flowId获取强制完结节点信息ScProductNode
     * @author: cuipeng
     * @creat_date: 2018/12/14
     **/
    public ProductNode findNodeQzWjById(Map map, List<ProductNode> sc_NodeList) {
        ValidateUtils.strNotEmpty(map.get("flowId"), ProductOrderExcption.class, "流程ID传入失败！");
        ProductNode nodeQzWj = productNodeDao.queryNodeQzWj(map);
       /* Assert.notNull(nodeQzWj, "强制完结节点出现异常，请联系管理员！");
        if (sc_NodeList == null && nodeQzWj != null) {
            throw new CommonExcption("流程出现异常，请联系管理员！");
        }*/
        return nodeQzWj;
    }

    /**
     * @Title:根据flowId获取放款节点信息ScProductNode
     * @author: cuipeng
     * @creat_date: 2018/12/14
     **/
    public ProductNode findNodeFkById(Map map, List<ProductNode> sc_NodeList) {
        ValidateUtils.strNotEmpty(map.get("flowId"), ProductOrderExcption.class, "流程ID传入失败！");
        ProductNode nodeFk = productNodeDao.queryNodeFk(map);
        //Assert.notNull(nodeFk, "放款节点出现异常，请联系管理员！");
        if (sc_NodeList == null && nodeFk != null) {
            //throw new CommonExcption("流程出现异常，请联系管理员！");
        }
        return nodeFk;
    }

    /**
     * @Title:根据flowId获取完结节点信息ScProductNode
     * @author:cuipeng
     * @creat_date: 2018/12/14
     **/
    public ProductNode findNodeWjById(Map map, List<ProductNode> sc_NodeList) {
        ValidateUtils.strNotEmpty(map.get("flowId"), ProductOrderExcption.class, "流程ID传入失败！");
        ProductNode nodeWj = productNodeDao.queryNodeWj(map);
        /*Assert.notNull(nodeWj, "完结节点出现异常，请联系管理员！");
        if (sc_NodeList == null && nodeWj != null) {
            throw new CommonExcption("流程出现异常，请联系管理员！");
        }*/
        return nodeWj;
    }

    /**
     * @Title:
     * @Description: TODO 保存节点信息
     * @param:
     * @return:
     * @throw:
     * @author: cuipeng
     * @creat_date: 2018/12/14
     **/
    @Transactional
    public void saveNode(ProductNode node, Map params) {
        UserEntity sessionUser = this.sessionManager.getCurrentUser();
        ValidateUtils.strNotEmpty(sessionUser, ProductOrderExcption.class, "未获取到登陆人，请重新登录！");
        Map tjmap = new HashMap();
        Long flowid = Long.parseLong(params.get("flowid").toString());
        tjmap.put("flowId", flowid);
        ProductNodeFlow scProNodeFlow = productNodeFlowDao.queryFlowById(tjmap);
        ValidateUtils.strNotEmpty(scProNodeFlow, ProductOrderExcption.class, "流程信息获取出现异常！");
        DggValidateUtil.notNull(params.get("version"),ProductOrderExcption.class,"获取节点版本异常");
        Long oldVersion = Long.parseLong(params.get("version").toString());
        //修改保存之前当前流程ID下面之前所有的节点信息状态都改为不可用
        //查询当前最新版本
        List<ProductNode> nodess = productNodeDao.queryByFlowId(new HashMap(){{
            put("flowId",flowid);
        }});
        if(nodess != null && nodess.size() > 0){
            if(!nodess.get(0).getVersion().equals(oldVersion)){
                throw new ProductOrderExcption("节点状态已经改变，请刷新页面再操作！");
            }
        }
        ProductNode p = new ProductNode();
        p.setProcessId(flowid);
        p.setVersion(oldVersion);
        productNodeDao.updateNodeFlag(p);
        JSONArray jsonArray = JSONArray.parseArray(params.get("jsonData").toString());
        if (jsonArray.size() > 0) {
            for (int i = 0; i < jsonArray.size(); i++) {
                ProductNode scProFlowNode = new ProductNode();
                JSONObject job = jsonArray.getJSONObject(i);  // 遍历 jsonarray 数组，把每一个对象转成 json 对象
                //验证节点名称不能超过10个字
                ValidateUtils.strNotEmpty(job.get("Nodename"), ProductOrderExcption.class, "节点名称不能空！");
                ValidateUtils.strNotEmpty(job.get("Nodecycle"), ProductOrderExcption.class, "办理周期不能空！");
//                Assert.isTrue(job.get("Nodename").toString().length()<=10,"节点名称不能超过10个字");
                ValidateUtils.isTrue(job.get("Nodename").toString().length()<=10, ProductOrderExcption.class, "节点名称不能超过10个字");
                if("接单".equals(job.get("Nodename")) && i != 0){
                    throw new ProductOrderExcption("节点名称不能为接单");
                }
                if("放款".equals(job.get("Nodename")) && i != jsonArray.size()-2){
                    throw new ProductOrderExcption("节点名称不能为放款");
                }
                if("完结".equals(job.get("Nodename")) && i != jsonArray.size()-1){
                    throw new ProductOrderExcption("节点名称不能为完结");
                }


                Long nodeid = DggKeyWorker.nextId();
                scProFlowNode.setId(nodeid);
                scProFlowNode.setName(job.get("Nodename").toString());
                scProFlowNode.setSort(Integer.parseInt(job.get("Xuhao").toString()));
                scProFlowNode.setProcessId(flowid);

                int handledate = Integer.parseInt(job.get("Nodecycle").toString());
//                Assert.isTrue(handledate > 0, "节点办理周期必须大于0！");
                ValidateUtils.isTrue(handledate > 0, ProductOrderExcption.class, "节点办理周期必须大于0");
                scProFlowNode.setHandleDate(handledate);
                scProFlowNode.setRelationField(job.get("Nodecruxfield").toString());
                scProFlowNode.setRelationFieldIds(job.get("nodecruxfieldids").toString());
                scProFlowNode.setIsKey(Integer.parseInt(job.get("Iscurxnode").toString()));


                scProFlowNode.setIsPunish(Integer.parseInt(job.get("isPunish").toString()));
                if(StringUtils.isNotEmpty(job.get("punishId"))){
                    scProFlowNode.setPunishId(Long.parseLong(job.get("punishId").toString()));
                    scProFlowNode.setPunishName(job.get("punishName")+"");
                }
                scProFlowNode.setIsWarning(Integer.parseInt(job.get("isWarning").toString()));

                scProFlowNode.setIsNaturalorWorkday(Integer.parseInt(job.get("isNaturalorWorkday").toString()));
                scProFlowNode.setFlag(1);
                scProFlowNode.setVersion(oldVersion+1);

                this.saveOpt(scProFlowNode, sessionUser);
                productNodeDao.save(scProFlowNode);
            }
           /* this.updateOpt(scProNodeFlow, sessionUser);
            productNodeFlowDao.update(scProNodeFlow);*/
        }
    }

    /**
     * @Title:复制流程保存
     * @author: cuipeng
     * @creat_date: 2018/12/14
     **/
    @Transactional
    @SuppressWarnings("all")
    public void copyFlowAndFlow(Map params) {
        UserEntity sessionUser = this.sessionManager.getCurrentUser();
        ValidateUtils.strNotEmpty(sessionUser, ProductOrderExcption.class, "未获取到登陆人，请重新登录！");
        if (StringUtils.isEmpty(params.get("flowId"))) {
            throw new CommonExcption("生产流程ID出现错误！");
        }
        if (StringUtils.isEmpty(params.get("orgId"))){
            throw new CommonExcption("所属部门ID为空！");
        }
        ProductNodeFlow newflow = new ProductNodeFlow();
        newflow.setDeptIds(Long.parseLong(String.valueOf(params.get("orgId"))));
        newflow.setDeptNames(getOrgNameById(Long.parseLong(String.valueOf(params.get("orgId")))));
        //newflow.setDeptNames(String.valueOf(params.get("selectTreeAddressIdCopy")));
        String buscode = String.valueOf(params.get("typeCodeCopy"));
        Map busCodeMap = cmsService.getTreeBookObj(buscode);
        Map BigFormatCodeMap = cmsService.getTreeBookObj(String.valueOf(busCodeMap.get("pcode")));
        newflow.setBigformatCode(String.valueOf(BigFormatCodeMap.get("code")));
        newflow.setBigformatName(String.valueOf(BigFormatCodeMap.get("name")));
        newflow.setManagementCycle(Integer.parseInt(String.valueOf(params.get("blDate"))));
        newflow.setIsnaturalorworkday(Integer.parseInt(String.valueOf(params.get("isnaturalorworkday"))));
        newflow.setExamineGrade(Integer.parseInt(String.valueOf(params.get("examinGrade"))));

        List<Map> ue = new ArrayList<>();
        String buslevel = String.valueOf(busCodeMap.get("levels"));
        int num = appearNumber(buslevel, "_");
        if (num == 3) {
            newflow.setBigformatCode(String.valueOf(busCodeMap.get("code")));
            newflow.setBigformatName(String.valueOf(busCodeMap.get("name")));
            newflow.setBusinessCode(null);
            newflow.setBusinessName(null);
            ue = productNodeFlowDao.findFlowEntityByBigFormatCode(newflow);
        } else if (num == 4) {
            newflow.setBigformatCode(String.valueOf(BigFormatCodeMap.get("code")));
            newflow.setBigformatName(String.valueOf(BigFormatCodeMap.get("name")));
            newflow.setBusinessCode(String.valueOf(busCodeMap.get("code")));
            newflow.setBusinessName(String.valueOf(busCodeMap.get("name")));
            ue = productNodeFlowDao.findFlowEntityByBusiness(newflow);
        } else {
            throw new CommonExcption("业态类型出现异常！");
        }
        if (ue.size() > 0) {
            throw new CommonExcption("保存失败，该业态流程已存在！");
        }
        long newflowid = DggKeyWorker.nextId();
        newflow.setId(newflowid);
        String flowno = cmsService.getBillNumber("LC");
        newflow.setFlowNo(flowno);
        newflow.setFlag(1);
        newflow.setIsOld(0);
        this.saveOpt(newflow, sessionUser);

        productNodeFlowDao.save(newflow);

        Map tjmap = new HashMap();
        tjmap.put("flowId", String.valueOf(params.get("flowId")));
        List<ProductNode> nodelist = productNodeDao.queryByFlowId(tjmap);
        ProductNodeFlow scProNodeFlow = productNodeFlowDao.queryFlowById(tjmap);

        if (nodelist.size() > 0) {
            for (ProductNode node : nodelist) {
                ProductNode newnode = new ProductNode();
                newnode.setId(DggKeyWorker.nextId());
                //newnode.setName(node.getName());
                newnode.setSort(node.getSort());
                newnode.setProcessId(newflowid);
                newnode.setHandleDate(node.getHandleDate());
                if (scProNodeFlow.getBigformatCode().equals(newflow.getBigformatCode())) {
                    newnode.setRelationField(node.getRelationField());
                    newnode.setRelationFieldIds(node.getRelationFieldIds());
                }
                newnode.setName(node.getName());
                newnode.setIsKey(node.getIsKey());
                newnode.setIsNaturalorWorkday(node.getIsNaturalorWorkday());
                newnode.setFlag(1);
                this.saveOpt(newnode, sessionUser);
                productNodeDao.save(newnode);
            }
        }
    }



    /**
     * @Title:复制流程保存(新)
     * @author: cuipeng
     * @creat_date: 2018/12/14
     **/
    @Transactional
    @SuppressWarnings("all")
    public void copyFlowAndFlowNew(Map params) {
        if (StringUtils.isEmpty(params.get("flowId"))) {
            throw new CommonExcption("生产流程ID出现错误！");
        }
        UserEntity sessionUser = this.sessionManager.getCurrentUser();
        ValidateUtils.strNotEmpty(sessionUser, ProductOrderExcption.class, "未获取到登陆人，请重新登录！");
        ValidateUtils.strNotEmpty(params.get("productId"), ProductOrderExcption.class, "产品ID不能为空！");
        //ValidateUtils.strNotEmpty(params.get("productName"), ProductOrderExcption.class, "产品名字不能为空！");
        //ValidateUtils.strNotEmpty(params.get("goodsId"), ProductOrderExcption.class, "商品ID不能为空！");
        //ValidateUtils.strNotEmpty(params.get("goodsName"), ProductOrderExcption.class, "商品名字不能为空！");
        //ValidateUtils.strNotEmpty(params.get("channelId"), ProductOrderExcption.class, "渠道ID不能为空！");
        //ValidateUtils.strNotEmpty(params.get("channelName"), ProductOrderExcption.class, "渠道名字不能为空！");
        ValidateUtils.strNotEmpty(params.get("blDate"), ProductOrderExcption.class, "办理周期不能为空！");
        ValidateUtils.strNotEmpty(params.get("isnaturalorworkday"), ProductOrderExcption.class, "是否工作日不能为空！");
        ValidateUtils.strNotEmpty(params.get("examinGrade"), ProductOrderExcption.class, "审核登记不能为空！");

        ProductNodeFlow flow = new ProductNodeFlow();
        Long productId = Long.parseLong(params.get("productId").toString());
        //换取产品中心id（只有查询流程时才使用）
        productId = commonService.getSerialId(productId);
        flow.setProductId(productId);
        //根据产品ID查询产品名字
        flow.setProductName(getProductNameByProductId(Long.parseLong(params.get("productId").toString())));

        String buscode = "";
        if (null == params.get("typeCodeAdd")) {//getOrgNameById()
            buscode = String.valueOf(params.get("typeCodeEdit"));
        } else {
            buscode = String.valueOf(params.get("typeCodeAdd"));
        }
        Map busCodeMap = cmsService.getTreeBookObj(buscode);
        Map BigFormatCodeMap = cmsService.getTreeBookObj(String.valueOf(busCodeMap.get("pcode")));

        flow.setBusinessName(String.valueOf(busCodeMap.get("name")));
        flow.setManagementCycle(Integer.parseInt(String.valueOf(params.get("blDate"))));
        flow.setIsnaturalorworkday(Integer.parseInt(String.valueOf(params.get("isnaturalorworkday"))));
        flow.setExamineGrade(Integer.parseInt(String.valueOf(params.get("examinGrade"))));

        String buslevel = String.valueOf(busCodeMap.get("levels"));
        int num = appearNumber(buslevel, "_");
        int count = 0;
        if (num == 3) {
            flow.setBigformatCode(String.valueOf(busCodeMap.get("code")));
            flow.setBigformatName(String.valueOf(busCodeMap.get("name")));
            flow.setBusinessCode(null);
            flow.setBusinessName(null);
            count = productNodeFlowDao.countByBigBusinessCodeAndProductId(flow);
        } else if (num == 4) {
            flow.setBigformatCode(String.valueOf(BigFormatCodeMap.get("code")));
            flow.setBigformatName(String.valueOf(BigFormatCodeMap.get("name")));
            flow.setBusinessCode(String.valueOf(busCodeMap.get("code")));
            flow.setBusinessName(String.valueOf(busCodeMap.get("name")));
            count = productNodeFlowDao.countByBusinessCodeAndProductId(flow);
        } else {
            throw new CommonExcption("业态类型出现异常！");
        }

        if (count>0) {
            throw new CommonExcption("保存失败，流程已存在！");
        }

        long newflowid = DggKeyWorker.nextId();
        flow.setId(newflowid);
        String flowno = cmsService.getBillNumber("LC");
        flow.setFlowNo(flowno);
        flow.setFlag(1);
        flow.setIsOld(1);
        this.saveOpt(flow, sessionUser);
        //保存
        productNodeFlowDao.save(flow);

        Map tjmap = new HashMap();
        tjmap.put("flowId", String.valueOf(params.get("flowId")));
        List<ProductNode> nodelist = productNodeDao.queryByFlowId(tjmap);
        ValidateUtils.isTrue(nodelist != null && nodelist.size()>0, ProductOrderExcption.class, "获取节点信息失败！");
        ProductNodeFlow scProNodeFlow = productNodeFlowDao.queryFlowById(tjmap);
        ValidateUtils.strNotEmpty(scProNodeFlow, ProductOrderExcption.class, "获取流程信息失败！");
        if (nodelist.size() > 0) {
            for (ProductNode node : nodelist) {
                ProductNode newnode = new ProductNode();
                newnode.setId(DggKeyWorker.nextId());
                //newnode.setName(node.getName());
                newnode.setSort(node.getSort());
                newnode.setProcessId(newflowid);
                newnode.setHandleDate(node.getHandleDate());
                if (scProNodeFlow.getBigformatCode().equals(flow.getBigformatCode())) {
                    newnode.setRelationField(node.getRelationField());
                    newnode.setRelationFieldIds(node.getRelationFieldIds());
                }
                newnode.setName(node.getName());
                newnode.setIsKey(node.getIsKey());
                newnode.setIsNaturalorWorkday(node.getIsNaturalorWorkday());

                newnode.setIsPunish(node.getIsPunish());//是否扣罚
                newnode.setPunishId(node.getPunishId());//扣罚ID
                newnode.setPunishName(node.getPunishName());//扣罚方案名字
                newnode.setIsWarning(node.getIsWarning());//是否预警
                newnode.setVersion(0L);//设置版本号
                newnode.setFlag(1);
                this.saveOpt(newnode, sessionUser);
                productNodeDao.save(newnode);
            }
        }
    }

    /**
     * public int indexOf(int ch, int fromIndex)
     * 返回在此字符串中第一次出现指定字符处的索引，从指定的索引开始搜索
     *
     * @param srcText
     * @param findText
     * @return
     */
    public static int appearNumber(String srcText, String findText) {
        int count = 0;
        int index = 0;
        while ((index = srcText.indexOf(findText, index)) != -1) {
            index = index + findText.length();
            count++;
        }
        return count;
    }

    public String getOrgNameById(Long orgId) {
        String orgName = "";
        try {
            Map map = cmsService.findOrg(orgId);
            orgName = map.get("name") + "";
        } catch (Exception e) {
            e.printStackTrace();
        }
        return orgName;
    }




    /**
     * 流程id查询节点
     * @param map
     * @return
     */
    public List<ProductNode> queryByFlowId(Map map) {
        return productNodeDao.queryByFlowId(map);
    }

    /**
     * 流程id查询节点和版本号
     * @param map
     * @return
     */
    public List<ProductNode> queryByFlowIdAndVersion(Map map) {

        return productNodeDao.queryByFlowIdAndVersion(map);
    }



    /**
     * 保存更新信息
     * @param params
     * @author: chenzaidong
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveNodeUpdate(Map params) throws Exception {
        Date date = new Date();
        //获取当前登录用户
        UserEntity userEntity = searchUtils.getcurrUser(params);
        ValidateUtils.strNotEmpty(userEntity, FlowNodeExcption.class, "未获取到登陆人，请重新登录！");

        //查询主订单
        ValidateUtils.strNotEmpty(StringUtils.isEmpty(params.get("id")), FlowNodeExcption.class, "生产订单ID不能为空！");
        ProductOrder productOrder = productOrderDao.selectByPrimaryKey(Long.parseLong(params.get("id").toString()));
        ValidateUtils.strNotEmpty(productOrder, ProductOrderExcption.class, "未查询到此生产主订单，请刷新列表！");

        //查询主订单状态是否是办理中
        ValidateUtils.isTrue(productOrder.getStatus().equals(ScProductConstant.RZSCORDER_STATUS02), ProductOrderExcption.class
                , "此订单当前状态不是办理中不能操作该订单，请刷新列表！");
        //查询是否有可以操作该订单
        //查询当前订单办理人
        List<Long> assis = new ArrayList<>();
        //协单人员
        HashMap<String, Object> map = new HashMap<>();
        map.put("scProductOrderId",productOrder.getId());
        List<Assistant> assistantList = assistantDao.query(map);
        if (assistantList.size() >= 1) {
            for (Assistant assistant : assistantList) {
                assis.add(assistant.getAssistUserId());
            }
        }

        //协单人员是不能操作放款和完结节点的
        if(!StringUtils.isEmpty(params.get("completenodename"))){
            if("放款".equals(params.get("completenodename").toString()) || "完结".equals(params.get("completenodename").toString())){
                if(!productOrder.getFlowUserId().equals(userEntity.getId())){
                    throw new ProductOrderExcption("放款和完结节点只能由该生产单的流程人员才能操作！");
                }
            }
        }
        //流程人员id
        assis.add(productOrder.getFlowUserId());
        ValidateUtils.isTrue(assis.contains(userEntity.getId()), ProductOrderExcption.class, "您不是该订单的流程人员或协单人员，不能进行该操作！");
        List<ProductNode> productNodeList = new ArrayList<>();
        ProductNode productNodeCon = new ProductNode();//保存查询出来的节点
        ProductNode productNode = null;
        List<ProductNode> allProductNodeList = new ArrayList<ProductNode>();
        if(StringUtils.isNotEmpty(productOrder.getNodeJson())){
            List<ProductNode> productNodes = JSONArray.parseArray(productOrder.getNodeJson(), ProductNode.class);
            for(ProductNode p : productNodes){
                if(Long.parseLong(params.get("completenodeid").toString()) == p.getId()){
                    productNodeList.add(p);
                    productNode = p;
                }
            }
        }else{
            //节点id查询节点
            productNodeList = productNodeDao.query(new HashMap<String, Object>() {{
                put("id", params.get("completenodeid"));
            }});

            ValidateUtils.strNotEmpty(productNodeList, ProductOrderExcption.class, "节点不存在，请刷新后重试");//节点不等于空
            productNode = productNodeList.get(0);
            Map nodeMap = new HashMap();
            nodeMap.put("flowId", productNode.getProcessId());
            ProductNodeFlow productNodeFlow = productNodeFlowDao.selectFlowById(nodeMap);
            int old = productNodeFlow.getIsOld()==null?0:productNodeFlow.getIsOld().intValue();
            if (old==0) {
                allProductNodeList = this.queryByFlowId(nodeMap);
            }else {
                allProductNodeList= this.queryByFlowIdAndVersion(nodeMap);
            }
            ValidateUtils.strNotEmpty(productNodeList, ProductOrderExcption.class, "对应流程不存在，请刷新后重试");
            //判断当前更新节点之前是否有关键节点没有更新
            Map<String,String> isKyeNodeMap = checkKeyNode(productNode.getProcessId(),productNode.getSort(),productOrder.getVersion(),productOrder.getId(),old);
            if (!"0".equals(isKyeNodeMap.get("code")+"")){
                ValidateUtils.isTrue(false,ProductOrderExcption.class, "请更新"+
                        isKyeNodeMap.get("msg")+"这"+isKyeNodeMap.get("size")+"个关键节点后再更新此节点信息");
            }
        }
        productOrder.setLatestEndNodeId(productNode.getId()); //最新完成节点id
        productOrder.setLatestEndNodeName(productNode.getName()); //最新完成节点名称
        productNodeCon = productNode;

        //更新主订单
        productOrder.setLatestEndUserId(userEntity.getId());//最新节点更新人id
        productOrder.setLatestEndUserName(userEntity.getRealName().concat(userEntity.getLoginName())); //最新节点更新人
        productOrder.setLatestEndUserOrgId(userEntity.getOrgId());//最新更新人部门id
        //查询所在部门
        OrganizationEntity org = organizationManager.findOrgEntityByOrgId(userEntity.getOrgId());
        if(org != null){
            productOrder.setFlowUserOrgId(org.getId());//流程人员部门ID
            productOrder.setFlowUserOrgName(org.getName());//流程人员部门名称
        }

        //如果当前更新节点是放款，更新已放款字段
        if(!StringUtils.isEmpty(params.get("completenodename"))){
            if("放款".equals(params.get("completenodename").toString())){
                productOrder.setIsLoan(1);
            }
            if("完结".equals(params.get("completenodename").toString())){
                //如果更新当前节点为完结需要判断是否放款
                List<ProductNodeOperating> productNodeOperatings = productNodeOperatingDao.queryPorductNodeOperatingByScProductId(Long.parseLong(params.get("id")+""));
                int fkCount = 0;
                for(ProductNodeOperating p : productNodeOperatings){
                    if("放款".equals(p.getNodeName())){
                        fkCount ++;
                        break;
                    }
                }
                ValidateUtils.isTrue(fkCount > 0, ProductOrderExcption.class, "请先更新放款节点后再更新完结节点！");
            }
        }

       //协单人员操作更新操作记录
        //当前登录用户如果是协办人
        List<Assistant> currentAssistantList = this.assistantDao.query(new HashMap<String, Object>() {{
            put("scProductOrderId", productOrder.getId());
            put("assistUserId", userEntity.getId());
        }});
        //更新协办记录
        if (currentAssistantList != null && currentAssistantList.size()>0) {
            productOrderService.updateScAssistants(assistantList, productNodeCon, userEntity);
        }

        //将页面录入的自定义字段保存到主订单
        setCustomizeNode(productOrder,params);

        //---------查询生产订单生产是否超期-----------
        List<ProductTimeStatus> productTimeStatusList = productTimeStatusDao.query(new HashMap<String, Object>() {{
            put("id", productOrder.getId());
        }});
        ProductTimeStatus productTimeStatus = null;
        if(productTimeStatusList== null  || productTimeStatusList.size()<1){
            /*throw new ProductOrderExcption("未查询到该主订单生产日期状态");*/
            productTimeStatus = productTimeStatusService.insertProductStatus(productOrder);
        }else{
            //超期表
            productTimeStatus = productTimeStatusList.get(0);
        }

        //判断如果是更新最后一个节点，则不对下一个节点时间设置
        List<Integer> sortList = new ArrayList<>();
        if (!productNode.getSort().equals(Integer.valueOf(allProductNodeList.size()+1))) {
            for (ProductNode nextProductNode : allProductNodeList) {
                if(productNode.getSort().equals(Integer.valueOf(nextProductNode.getSort() -1))) {
                    Date currentDate = commonService.getDateFromStartByType(date,
                            nextProductNode.getHandleDate(), 0L,
                            nextProductNode.getIsNaturalorWorkday());
                    productTimeStatus.setNodeEndTime(currentDate);
                    productTimeStatus.setNodeStartTime(date);
                    productTimeStatus.setNodeId(nextProductNode.getId());
                    productTimeStatus.setNodeName(nextProductNode.getName());
                    productTimeStatus.setNodeProcessTime(nextProductNode.getHandleDate());
                    productTimeStatus.setNodeProcessTimeType(nextProductNode.getIsNaturalorWorkday());
                }
            }
        }
        //保存更新节点记录
        ProductNodeOperating productNodeOperating = saveScProductOperating(productOrder, productNodeCon, params, productTimeStatus);
        productOrder.setLatestEndNodeTime(date); //最新完成节点时间

        //判断是否选择的完结
        if ("完结".equals(productOrder.getLatestEndNodeName()) || "强制完结".equals(productOrder.getLatestEndNodeName())) {
            //-------判断完结状态(正常，超期，强制)----------
            productOrderService.getScProductConstant(productOrder, productTimeStatus);
            productTimeStatus.setFlag(0); //完结后不执行

            //更新订单超期表的节点超期状态
            String nodeTimeStatus = productNodeOperating.getNodeTimeStatus();
            productTimeStatus.setNodeTimeStatus(nodeTimeStatus);//这里做了修改,每次节点更新都更新订单的节点超期状态
        } else {
            String nodeTimeStatus = productNodeOperating.getNodeTimeStatus();
            productTimeStatus.setNodeTimeStatus(nodeTimeStatus);//这里做了修改,每次节点更新都更新订单的节点超期状态
        }

        //设置下次跟进时间 ，没用使用这个值
        if(!StringUtils.isEmpty(params.get("nextFollowTime"))){
            productTimeStatus.setNextFollowTime(DateUtils.getDate(params.get("nextFollowTime").toString(), "yyyy-MM-dd"));
        }

        //更新主订单
        this.updateOpt(productOrder, userEntity);
        productOrderDao.updateByPrimaryKeySelective(productOrder);

        //保存更新节点记录表
        this.saveOpt(productNodeOperating, userEntity);
        OrganizationEntity operatedOrgan = organizationManager.findOrgEntityByOrgId(userEntity.getOrgId());
        productNodeOperating.setUpdaterOrgName(operatedOrgan.getName());
        productNodeOperating.setCreaterOrgName(operatedOrgan.getName());
        productNodeOperatingDao.insert(productNodeOperating);

        //更新超期表
        this.updateOpt(productTimeStatus, userEntity);
        productTimeStatusDao.updateByPrimaryKey(productTimeStatus);
        //调用同步子订单接口  结项再处理
        if ("完结".equals(productOrder.getLatestEndNodeName()) || "强制完结".equals(productOrder.getLatestEndNodeName())) {

            Integer status = 1;
            Map orderMap = new HashMap();
            orderMap.put("orderId",productOrder.getOrderId());
            orderMap.put("flag",0);
            List<ProductOrderDto> rzProductOrderList = productOrderDao.scOrderWithPage(orderMap);

            for (ProductOrder pOrder : rzProductOrderList) {
                if (!pOrder.getStatus().equals(ScProductConstant.RZSCORDER_STATUS17)&&!pOrder.getStatus().equals(ScProductConstant.RZSCORDER_STATUS19)) { //不是生产完结和超期完结的
                    status++;
                }
            }
            if(status == 1){
                //调同步接口/
                orfApiService.updateOrder(productOrder.getOrderId(), userEntity.getId(), "ORF_DDZT_6", null);
            }
        }

        //放款时去推送订单数据到薪酬系统
        if("完结".equals(params.get("completenodename").toString())){
            recognitionService.pushPayToSalary(productOrder.getId());
        }
        //通过MQ推送消息到UC
        CustomerRecord customerRecord = new CustomerRecord();
        customerRecord.setCustomerId(productOrder.getCustomerId());
        customerRecord.setTableName("rzsc_product_order");
        customerRecord.setTableId(productOrder.getId());
        customerRecord.setTableNo(productOrder.getScProductOrderNo());
        customerRecord.setRemarkType(ScNoteType.RZSC_NOTE_CODE4);
        customerRecord.setCreaterId(userEntity.getId());
        //设置备注
        if (null != params.get("remark") && !"".equals(params.get("remark"))) {
            customerRecord.setContent( params.get("remark").toString());
        }else{
            customerRecord.setContent(params.get("completenodename") == null ? "更新进度":params.get("completenodename").toString());
        }
        MQMessageSendUtil.ucMessageSend(customerRecord);
        //同步生产单状态给企大宝
        MQMessageSendUtil.qdsMessageSend(productOrder,productNode,userEntity);
    }

    /**
     * 将节点自定义字段内容，保存到主订单中
     */
    public void setCustomizeNode(ProductOrder productOrder ,Map params){
        //评估公司
        if (!StringUtils.isEmpty(params.get("escrowCompany"))) {
            productOrder.setEscrowCompany(params.get("escrowCompany").toString());
        }

        //评估价格
        if (!StringUtils.isEmpty(params.get("appraisalCost"))) {

            boolean appraisalCost = RegularValidUtils.matches(ModuleCodeConstant.REGEX_AMOUNT, params.get("appraisalCost").toString());
            if (!appraisalCost) {
                throw new ProductOrderExcption("评估费用格式不正确，金额最大8位数，精度是小数点后两位");
            }else{
                productOrder.setAppraisalCost(new BigDecimal(params.get("appraisalCost").toString()));
            }
        }

        //征信
        if (!StringUtils.isEmpty(params.get("credit"))) {
            productOrder.setCredit(params.get("credit").toString());
        }

        //申请金额（贷款额度）
        //20190523产品要求更新该关联字段时同步更新AppliedAmount申请贷款金额
        if (!StringUtils.isEmpty(params.get("loanAmounts"))) {
            boolean loanAmount = RegularValidUtils.matches(ModuleCodeConstant.REGEX_AMOUNT, params.get("loanAmounts").toString());
            if (!loanAmount) {
                throw new ProductOrderExcption("申请金额格式不正确，金额最大8位数，精度是小数点后两位");
            }else{
                productOrder.setLoanAmount(new BigDecimal(params.get("loanAmounts").toString()));
                productOrder.setAppliedAmount(new BigDecimal(params.get("loanAmounts").toString()));
            }
        }

        //签申请时间
        if (!StringUtils.isEmpty(params.get("applicationTime"))) {
            productOrder.setApplicationTime( DateUtils.getDate(params.get("applicationTime").toString(), "yyyy-MM-dd"));
        }

        //报审时间
        if (!StringUtils.isEmpty(params.get("reportTime"))) {
            productOrder.setReportTime( DateUtils.getDate(params.get("reportTime").toString(), "yyyy-MM-dd"));
        }

        //审核通过时间
        if (!StringUtils.isEmpty(params.get("approveTime"))) {
            productOrder.setApproveTime( DateUtils.getDate(params.get("approveTime").toString(), "yyyy-MM-dd"));
        }

        //通过金额
        if (!StringUtils.isEmpty(params.get("approveMoney"))) {
            boolean approveMoney = RegularValidUtils.matches(ModuleCodeConstant.REGEX_AMOUNT, params.get("approveMoney").toString());
            if (!approveMoney) {
                throw new ProductOrderExcption("通过金额格式不正确，金额最大8位数，精度是小数点后两位");
            }else{
                productOrder.setApproveMoney(new BigDecimal(params.get("approveMoney").toString()));
            }
        }

        //结案银行
        if (!StringUtils.isEmpty(params.get("settlementBank"))) {
            productOrder.setSettlementBank(params.get("settlementBank").toString());
        }

        //垫资注销时间
        if (!StringUtils.isEmpty(params.get("advanceFundCancel"))) {
            productOrder.setAdvanceFundCancel( DateUtils.getDate(params.get("advanceFundCancel").toString(), "yyyy-MM-dd"));
        }

        //抵押时间
        if (!StringUtils.isEmpty(params.get("mortgageTime"))) {
            productOrder.setMortgageTime( DateUtils.getDate(params.get("mortgageTime").toString(), "yyyy-MM-dd"));
        }

        //取他权时间
        if (!StringUtils.isEmpty(params.get("takeHisTime"))) {
            productOrder.setTakeHisTime( DateUtils.getDate(params.get("takeHisTime").toString(), "yyyy-MM-dd"));
        }

        //放款时间
        if (!StringUtils.isEmpty(params.get("loanTime"))) {
            productOrder.setLoanTime( DateUtils.getDate(params.get("loanTime").toString(), "yyyy-MM-dd"));
        }

        //放款时长(天)
        if (!StringUtils.isEmpty(params.get("loanTimeDay"))) {
            boolean loanTimeDay = RegularValidUtils.matches("^[1-9]\\d{0,2}$", params.get("loanTimeDay").toString());
            if (!loanTimeDay) {
                throw new ProductOrderExcption("放款时长只能3位以下正整数");
            }else{
                productOrder.setLoanTimeDay(new Integer(params.get("loanTimeDay").toString()));
            }
        }

        //还款到期日期
        if (!StringUtils.isEmpty(params.get("repaymentDate"))) {
            productOrder.setRepaymentDate( DateUtils.getDate(params.get("repaymentDate").toString(), "yyyy-MM-dd"));
        }

        //还款时间,因为可以根据选择值输入，可以输入字符串
        if (!StringUtils.isEmpty(params.get("dateOfLoan"))) {
            productOrder.setDateOfLoan(params.get("dateOfLoan").toString());
           // productOrder.setRepaymentDate( DateUtils.getDate(params.get("dateOfLoan").toString(), "yyyy-MM-dd"));
        }

        //还款方式
        if (!StringUtils.isEmpty(params.get("wayOfLoan"))) {
            productOrder.setWayOfLoan(params.get("wayOfLoan").toString());
        }

        //后台结算金额
        if (!StringUtils.isEmpty(params.get("settlementAmount"))) {
            boolean settlementAmount = RegularValidUtils.matches(ModuleCodeConstant.REGEX_AMOUNT, params.get("settlementAmount").toString());
            if (!settlementAmount) {
                throw new ProductOrderExcption("后台结算金额格式不正确，金额最大8位数，精度是小数点后两位");
            }else{
                productOrder.setSettlementAmount(new BigDecimal(params.get("settlementAmount").toString()));
            }
        }

        //渠道返点
        if (!StringUtils.isEmpty(params.get("channelRebates"))) {
            boolean channelRebates = RegularValidUtils.matches(ModuleCodeConstant.REGEX_AMOUNT, params.get("channelRebates").toString());
            if (!channelRebates) {
                throw new ProductOrderExcption("渠道返点格式不正确，金额最大8位数，精度是小数点后两位");
            }else{
                productOrder.setChannelRebates(new BigDecimal(params.get("channelRebates").toString()));
            }
        }

        //对外返点
        if (!StringUtils.isEmpty(params.get("foreignRebates"))) {
            boolean foreignRebates = RegularValidUtils.matches(ModuleCodeConstant.REGEX_AMOUNT, params.get("foreignRebates").toString());
            if (!foreignRebates) {
                throw new ProductOrderExcption("对外返点格式不正确，金额最大8位数，精度是小数点后两位");
            }else{
                productOrder.setForeignRebates(new BigDecimal(params.get("foreignRebates").toString()));
            }
        }

        //每期还款金额/月
        if (!StringUtils.isEmpty(params.get("installmentRepayment"))) {
            boolean installmentRepayment = RegularValidUtils.matches(ModuleCodeConstant.REGEX_AMOUNT, params.get("installmentRepayment").toString());
            if (!installmentRepayment) {
                throw new ProductOrderExcption("每期还款金额/月格式不正确，金额最大8位数，精度是小数点后两位");
            }else{
                productOrder.setInstallmentRepayment(new BigDecimal(params.get("installmentRepayment").toString()));
            }
        }

        //放款金额
        if (!StringUtils.isEmpty(params.get("loanMoney"))) {
            boolean loanMoney = RegularValidUtils.matches(ModuleCodeConstant.REGEX_AMOUNT, params.get("loanMoney").toString());
            if (!loanMoney) {
                throw new ProductOrderExcption("放款金额格式不正确，金额最大8位数，精度是小数点后两位");
            }else{
                productOrder.setLoanMoney(new BigDecimal(params.get("loanMoney").toString()));
            }
        }
        //资金用途
        if(!StringUtils.isEmpty(params.get("capitalUses"))){
            productOrder.setPurpose(Integer.parseInt(params.get("capitalUses")+""));
        }

        if (!StringUtils.isEmpty(params.get("remark"))) {
            productOrder.setRemark(params.get("remark").toString());//备注
            productOrder.setLastRemark(params.get("remark").toString());//最新备注内容
            productOrder.setLastRemarkTime(new Date());//最新备注时间
        }

        //产权性质
        if (!StringUtils.isEmpty(params.get("interestType"))) {
            String interestType = String.valueOf(params.get("interestType"));
//            参数验证1住宅2商铺3公寓
            if(!"1".equals(interestType)&&!"2".equals(interestType)&&!"3".equals(interestType)){
                throw new ProductOrderExcption("产权性质参数错误，请重新填写");
            }
            productOrder.setInterestType(Integer.valueOf(interestType));//产权性质
        }
        //地址
        if (!StringUtils.isEmpty(params.get("address"))) {
            String address = String.valueOf(params.get("address")) ;
            ValidateUtils.isTrue(address.length()<=50, ProductOrderExcption.class, "地址不能超过50，请核查后再提交");
            productOrder.setAddress(address);
        }

        //地址
        if (!StringUtils.isEmpty(params.get("area"))) {
            String area = String.valueOf(params.get("area")) ;
            ValidateUtils.isTrue(area.length()<=50, ProductOrderExcption.class, "地址不能超过50，请核查后再提交");
            productOrder.setArea(area);
        }

        //按揭/全款
        if (!StringUtils.isEmpty(params.get("refundType"))) {
            String refundType = String.valueOf(params.get("refundType"));
//            参数验证1按揭2全款
            if(!"1".equals(refundType)&&!"2".equals(refundType)){
                throw new ProductOrderExcption("按揭/全款参数错误，请重新填写");
            }
            productOrder.setRefundType(Integer.valueOf(refundType));//按揭/全款
        }

    }


    /**
     *更新节点时的 保存节点记录信息
     * @param productOrder  主订单
     * @param scProductNode  节点对象
     * @param map   页面传递的值
     * @param scProductTimeStatus   节点设置的超期时间
     * @author: chenzaidong
     * @return
     */
    @Transactional
    public ProductNodeOperating saveScProductOperating(ProductOrder productOrder, ProductNode scProductNode, Map map, ProductTimeStatus scProductTimeStatus) {
        //用户对象
        UserEntity flowUser = userservice.findUserById(productOrder.getFlowUserId());//获取当前办理人员
        ValidateUtils.strNotEmpty(flowUser, ProductOrderExcption.class, "未获取到当前生产订单流程人员信息！");

        //部门对象
        OrganizationEntity org = organizationManager.findOrgEntityByOrgId(flowUser.getOrgId());
        ValidateUtils.strNotEmpty(org, ProductOrderExcption.class, "未获取到当前生产订单流程人员部门信息！");

        //流程记录
        ProductNodeOperating productNodeOperating = new ProductNodeOperating();
        productNodeOperating.setId(DggKeyWorker.nextId());//设置id
        productNodeOperating.setRemarksType(1);   //(记录类型  1：节点更新，2：备注)
        productNodeOperating.setScProductOrderId(productOrder.getId());//主订单id
        productNodeOperating.setScProductOrderNo(productOrder.getScProductOrderNo());//生产订单编号
        productNodeOperating.setFlowOrgId(org.getId());//部门id
        productNodeOperating.setFlowOrgName(org.getName());//部门名称
        productNodeOperating.setFlowUserId(productOrder.getFlowUserId());//流程人员id
        productNodeOperating.setFlowUserName(productOrder.getFlowUserName());//流程人员名字
        productNodeOperating.setOrderStatus(productOrder.getStatus());//生产订单状态
        productNodeOperating.setNodeId(productOrder.getLatestEndNodeId());//节点id
        productNodeOperating.setNodeName(productOrder.getLatestEndNodeName());//节点名称
        productNodeOperating.setNodeProcessTimeType(scProductNode.getIsNaturalorWorkday().toString()); //节点办理时长类型 自然日or工作日(1:工作日；2：自然日)
        productNodeOperating.setNodeOpetateTime(new Date());//节点完成时间
        productNodeOperating.setCommission(scProductNode.getCommission());
        productNodeOperating.setBrokerage(scProductNode.getBrokerage());
        //设置创建人部门
        UserEntity currentUser = searchUtils.getcurrUser(map);
        OrganizationEntity newOrg = organizationManager.findOrgEntityByOrgId(currentUser.getOrgId());
        productNodeOperating.setCreaterOrgName(newOrg.getCreaterName());

        //设置备注
        if (null != map.get("remark") && !"".equals(map.get("remark"))) {
            productNodeOperating.setRemark( map.get("remark").toString());
        }else{
            productNodeOperating.setRemark(map.get("completenodename").toString());
        }

        //获取当前节点的配置的计算出的超期时间
        Date currentDate = commonService.getDateFromStartByType(productOrder.getLatestEndNodeTime(),
                scProductNode.getHandleDate(), scProductTimeStatus.getNodeSuspendMillisecond() == null ? 0 : scProductTimeStatus.getNodeSuspendMillisecond(),
                scProductNode.getIsNaturalorWorkday());

        productNodeOperating.setNodeProcessTime(scProductNode.getHandleDate());
        productNodeOperating.setNodeStartTime(productOrder.getLatestEndNodeTime());
        productNodeOperating.setNodeEndTime(currentDate);
        //判断当前节点是否超期
        if (currentDate.getTime() >= System.currentTimeMillis()) {
            productNodeOperating.setNodeTimeStatus(ScProductConstant.NORMAL); //节点超期    正常状态
        } else {
            productNodeOperating.setNodeTimeStatus(ScProductConstant.TIME_OUT); //节点超期状态  超期
            String date = DateUtils.transTime(currentDate, new Date());
            productNodeOperating.setNodeOverdueTime(date); //节点超期时间
            //进行节点超期扣罚操作
            this.nodePunish(productNodeOperating, productOrder, scProductNode);
        }



        return productNodeOperating;
    }

    /**
     * 流程节点数据补充（导入以前老数据 没有接单，放款，强制完结，完结这四个固定节点的时候 自动补充进去）
     *
     */
    @Transactional
    public void supplementFlowNode(){
        UserEntity sessionUser = this.sessionManager.getCurrentUser();
        //查询所有流程
        Map map = new HashMap();
        List<ProductNodeFlow> list = productNodeFlowDao.queryWithPage(map);
        for(ProductNodeFlow f : list) {
            Long id = f.getId();
            // List<ProductNode>
            Map map1 = new HashMap();
            map1.put("processId", id);
            map1.put("flag", 1);
            List<ProductNode> nodeList = productNodeDao.query(map1);
            int countjd = 0;//接单
            int countfk = 0;//放款
            /*int countqzwj = 0;//强制完结*/
            int countwj = 0;//完结
            for (int i = 0; i < nodeList.size(); i++) {
                if ("接单".equals(nodeList.get(i).getName())) {
                    countjd++;
                }
                if ("放款".equals(nodeList.get(i).getName())) {
                    countfk++;
                }
               /* if ("强制完结".equals(nodeList.get(i).getName())) {
                    countqzwj++;
                }*/
                if ("完结".equals(nodeList.get(i).getName())) {
                    countwj++;
                }
            }
            if (countjd == 0) {//说明节点里面没有接单节点这个初始固定节点需要加进去
                ProductNode jdnode = new ProductNode();
                jdnode.setId(DggKeyWorker.nextId());
                jdnode.setName("接单");
                jdnode.setHandleDate(1);
                jdnode.setIsNaturalorWorkday(1);
                jdnode.setIsKey(1);
                jdnode.setSort(1);
                jdnode.setProcessId(id);
                jdnode.setFlag(1);
                this.saveOpt(jdnode, sessionUser);
                productNodeDao.save(jdnode);
                //然后修改后面节点的sort 依次加1
                for (ProductNode l : nodeList) {
                    ProductNode jd = new ProductNode();
                    jd.setId(l.getId());
                    productNodeDao.updateNodeSort(jd);
                }
            }
            if (countwj == 0) {//说明节点里面没有完结节点这个初始固定节点需要加进去
                //计算完结的sort
                List<ProductNode> nodeList1 = productNodeDao.query(map1);//因为前面有可能会新增 所有 要重新查询才能算出最新的长度
                int sort = nodeList1.size();
                ProductNode wjnode = new ProductNode();
                wjnode.setId(DggKeyWorker.nextId());
                wjnode.setName("完结");
                wjnode.setHandleDate(1);
                wjnode.setIsNaturalorWorkday(1);
                wjnode.setIsKey(1);
                wjnode.setSort(sort + 1);
                wjnode.setProcessId(id);
                wjnode.setFlag(1);
                this.saveOpt(wjnode, sessionUser);
                productNodeDao.save(wjnode);
                //因为完结是最后一个节所以后面不需要去注意后面的sort+1问题
            }
           /* if (countfk == 0) {//说明节点里面没有放款节点这个初始固定节点需要加进去
                List<ProductNode> nodeList3 = productNodeDao.query(map1);//因为前面有可能会新增 所有 要重新查询才能算出最新的长度
                //计算放款的sort
                int sort = nodeList3.size() - 1;//因为强制完结是倒数第三个
                ProductNode fknode = new ProductNode();
                fknode.setId(DggKeyWorker.nextId());
                fknode.setName("放款");
                fknode.setHandleDate(1);
                fknode.setIsNaturalorWorkday(1);
                fknode.setIsKey(1);
                fknode.setSort(sort);
                fknode.setProcessId(id);
                fknode.setFlag(1);
                this.saveOpt(fknode, sessionUser);
                productNodeDao.save(fknode);
                //然后修改后面节点的sort 依次加1（强制完结和完结的sort需要+1）接单 1  2  强制完结  完结
                ProductNode wj = new ProductNode();
                wj.setId(nodeList3.get(nodeList3.size() - 1).getId());
                productNodeDao.updateNodeSort(wj);
                ProductNode qzwj = new ProductNode();
                qzwj.setId(nodeList3.get(nodeList3.size() - 2).getId());
                productNodeDao.updateNodeSort(qzwj);

            }*/


        }

    }

    public int getWorkDays(Map map)throws Exception{
        String productId = map.get("productId")+"";
        String endTime = map.get("loanTime")+"";
        if(StringUtils.isEmpty(productId)){
            throw new CommonExcption("生产订单ID不能为空！");
        }
        if(StringUtils.isEmpty(endTime)){
            throw new CommonExcption("放款时间不能为空！");
        }
        ProductOrder productOrder = productOrderDao.selectByPrimaryKey(Long.parseLong(productId));
        if(StringUtils.isEmpty(productOrder)){
            throw new CommonExcption("没有查到对应的生产单信息！");
        }
        Date recerveTime = productOrder.getReceiveOrderDate();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        String startTime = formatter.format(recerveTime);
        return DateUtils.getWorkDays(startTime,endTime);
    }

    /**
     * 根据产品ID查询产品名字
     * @param id
     * @return
     */
    public String getProductNameByProductId(Long id){
        Map product = commonService.getProductInfo(id);
        ValidateUtils.strNotEmpty(product, ProductOrderExcption.class, "获取产品信息失败！");
        return product.get("name")+"";
    }

    /**
     *  验证当前需要更新的节点之前是否有关键节点没有更新
     */
    public Map<String,String> checkKeyNode(Long processId,Integer sort,Long version,Long productId,int old){
        Map<String,String> map = new HashMap<>();
        List<ProductNode> list = productNodeDao.countIsKey(new HashMap(){{
            put("productId",productId);
            put("processId",processId);
            put("version",version);
            put("oldData",old);
            put("sort",sort);
        }});
        StringBuilder sb = new StringBuilder();
        if(list != null && list.size() > 0){//说明有关键节点没有更新
            for(ProductNode p : list){
                sb.append("["+p.getName()+"]");
            }
            map.put("code","1");
            map.put("msg",sb.toString());
            map.put("size",list.size()+"");
        }else{//说明当前节点前面所有的关键节点都已更新
            map.put("code","0");
        }
        return map;
    }

    /**
     * 根据渠道+商品查询节点信息
     */
    public List<ProductNode> nodesByGoodsIdChannelId(Long channelId,Long goodsId){
        ValidateUtils.strNotEmpty(channelId, ProductOrderExcption.class, "渠道ID为空！");
        ValidateUtils.strNotEmpty(goodsId, ProductOrderExcption.class, "商品ID为空！");
        List<ProductNode> list = productNodeDao.queryNodeByChannelIdAndGoodsId(new HashMap(){{
            put("channelId",channelId);
            put("goodsId",goodsId);
        }});
        return list;
    }


    /**
     * @Author Quanlin Wan
     * @Description //TODO 节点超期扣罚
     * @Date 10:01 2019/4/16
     * @Param
     * @return
     **/
    public void nodePunish(ProductNodeOperating productNodeOperating,ProductOrder productOrder,ProductNode node){
        Long punishRecordNum=nodeTimeOutPunishDao.selectByNodeIdAndScId(new HashMap(2){{
            put("nodeId", node.getId());
            put("scProductOrderId", productOrder.getId());
        }});

        int isPunish = node.getIsPunish()==null?2:node.getIsPunish().intValue();
        if(isPunish==1&&punishRecordNum.equals(0L)){
            PunishDetail punishDetail= punishDetailDao.queryPunishDetailByPunishId(new HashMap(){{
                put("punishId", node.getPunishId());
            }});
            Date timeout = productNodeOperating.getNodeEndTime();
            Date now = new Date();
            NodeTimeOutPunish nodeTimeoutPunish = new NodeTimeOutPunish();
            nodeTimeoutPunish.setId(DggKeyWorker.nextId());
            nodeTimeoutPunish.setFlowUserId(productNodeOperating.getFlowUserId());
            nodeTimeoutPunish.setFlowUserName(productNodeOperating.getFlowUserName());
            nodeTimeoutPunish.setProductOrgId(productOrder.getProductOrgId());
            nodeTimeoutPunish.setProductOrgName(productOrder.getProductOrgName());
            nodeTimeoutPunish.setOrderId(productOrder.getOrderId());
            nodeTimeoutPunish.setOrderNo(productOrder.getOrderNo());
            nodeTimeoutPunish.setScProductOrderId(productOrder.getId());
            nodeTimeoutPunish.setScProductOrderNo(productOrder.getScProductOrderNo());
            nodeTimeoutPunish.setNoId(productNodeOperating.getNodeId());
            nodeTimeoutPunish.setNoName(productNodeOperating.getNodeName());
            nodeTimeoutPunish.setTimeOutTime(timeout);
            nodeTimeoutPunish.setPunishTime(now);
            nodeTimeoutPunish.setPoints(punishDetail.getConductPoints());
            nodeTimeoutPunish.setMoney(punishDetail.getMoney());
            nodeTimeoutPunish.setFlage(0);
            nodeTimeoutPunish.setCreateTime(now);
            nodeTimeOutPunishDao.save(nodeTimeoutPunish);
        }


    }
    /**
     * 兼容呱呱云产品
     * 获取流程配置信息
     * @return
     */
    @Transactional
    public void insertProcessConfig() {
        Map params = new HashMap();
        //查询产品对应关系表
        List<Map> proNewOlds = productNodeFlowDao.getProNewOld();
        Map paramNew = new HashMap();
        for(Map map:proNewOlds){
            params.put("productId",Long.parseLong(map.get("old_id").toString()));
            ProductNodeFlow node = productNodeFlowDao.queryFlowAndNodeVersionByBusinessAndProductId(params);
            if(node != null){
                paramNew.put("flowId",node.getId());
                paramNew.put("typeCodeAdd",node.getBusinessCode());
                paramNew.put("productId",map.get("id").toString());
                paramNew.put("blDate",node.getManagementCycle());
                paramNew.put("isnaturalorworkday",node.getIsnaturalorworkday());
                paramNew.put("examinGrade",node.getExamineGrade());
                this.copyFlowG(paramNew);
                productNodeFlowDao.updateroNewOld(Long.parseLong(map.get("id").toString()));
            }
        }
    }
    private void copyFlowG(Map params) {
        if (StringUtils.isEmpty(params.get("flowId"))) {
            throw new CommonExcption("生产流程ID出现错误！");
        }
        UserEntity sessionUser = new UserEntity();
        sessionUser.setId(3242L);
        sessionUser.setRealName("郑有");
        sessionUser.setLoginName("4222291");
        sessionUser.setOrgId(1L);
        ValidateUtils.strNotEmpty(sessionUser, ProductOrderExcption.class, "未获取到登陆人，请重新登录！");
        ValidateUtils.strNotEmpty(params.get("productId"), ProductOrderExcption.class, "产品ID不能为空！");
        ValidateUtils.strNotEmpty(params.get("blDate"), ProductOrderExcption.class, "办理周期不能为空！");
        ValidateUtils.strNotEmpty(params.get("isnaturalorworkday"), ProductOrderExcption.class, "是否工作日不能为空！");
        ValidateUtils.strNotEmpty(params.get("examinGrade"), ProductOrderExcption.class, "审核登记不能为空！");

        ProductNodeFlow flow = new ProductNodeFlow();
        Long productId = Long.parseLong(params.get("productId").toString());
        //换取产品中心id（只有查询流程时才使用）
        productId = commonService.getSerialId(productId);
        flow.setProductId(productId);
        //根据产品ID查询产品名字
        flow.setProductName(getProductNameByProductId(Long.parseLong(params.get("productId").toString())));

        String buscode = "";
        if (null == params.get("typeCodeAdd")) {
            buscode = String.valueOf(params.get("typeCodeEdit"));
        } else {
            buscode = String.valueOf(params.get("typeCodeAdd"));
        }
        Map busCodeMap = cmsService.getTreeBookObj(buscode);
        Map BigFormatCodeMap = cmsService.getTreeBookObj(String.valueOf(busCodeMap.get("pcode")));

        flow.setBusinessName(String.valueOf(busCodeMap.get("name")));
        flow.setManagementCycle(Integer.parseInt(String.valueOf(params.get("blDate"))));
        flow.setIsnaturalorworkday(Integer.parseInt(String.valueOf(params.get("isnaturalorworkday"))));
        flow.setExamineGrade(Integer.parseInt(String.valueOf(params.get("examinGrade"))));

        String buslevel = String.valueOf(busCodeMap.get("levels"));
        int num = appearNumber(buslevel, "_");
        int count = 0;
        if (num == 3) {
            flow.setBigformatCode(String.valueOf(busCodeMap.get("code")));
            flow.setBigformatName(String.valueOf(busCodeMap.get("name")));
            flow.setBusinessCode(null);
            flow.setBusinessName(null);
            count = productNodeFlowDao.countByBigBusinessCodeAndProductId(flow);
        } else if (num == 4) {
            flow.setBigformatCode(String.valueOf(BigFormatCodeMap.get("code")));
            flow.setBigformatName(String.valueOf(BigFormatCodeMap.get("name")));
            flow.setBusinessCode(String.valueOf(busCodeMap.get("code")));
            flow.setBusinessName(String.valueOf(busCodeMap.get("name")));
            count = productNodeFlowDao.countByBusinessCodeAndProductId(flow);
        } else {
            throw new CommonExcption("业态类型出现异常！");
        }

        if (count>0) {
            throw new CommonExcption("保存失败，流程已存在！");
        }

        long newflowid = DggKeyWorker.nextId();
        flow.setId(newflowid);
        String flowno = cmsService.getBillNumber("LC");
        flow.setFlowNo(flowno);
        flow.setFlag(1);
        flow.setIsOld(1);
        this.saveOpt(flow, sessionUser);
        //保存
        productNodeFlowDao.save(flow);

        Map tjmap = new HashMap();
        tjmap.put("flowId", String.valueOf(params.get("flowId")));
        List<ProductNode> nodelist = productNodeDao.queryByFlowId(tjmap);
        ValidateUtils.isTrue(nodelist != null && nodelist.size()>0, ProductOrderExcption.class, "获取节点信息失败！");
        ProductNodeFlow scProNodeFlow = productNodeFlowDao.queryFlowById(tjmap);
        ValidateUtils.strNotEmpty(scProNodeFlow, ProductOrderExcption.class, "获取流程信息失败！");
        if (nodelist.size() > 0) {
            for (ProductNode node : nodelist) {
                ProductNode newnode = new ProductNode();
                newnode.setId(DggKeyWorker.nextId());
                newnode.setSort(node.getSort());
                newnode.setProcessId(newflowid);
                newnode.setHandleDate(node.getHandleDate());
                if (scProNodeFlow.getBigformatCode().equals(flow.getBigformatCode())) {
                    newnode.setRelationField(node.getRelationField());
                    newnode.setRelationFieldIds(node.getRelationFieldIds());
                }
                newnode.setName(node.getName());
                newnode.setIsKey(node.getIsKey());
                newnode.setIsNaturalorWorkday(node.getIsNaturalorWorkday());

                newnode.setIsPunish(node.getIsPunish());//是否扣罚
                newnode.setPunishId(node.getPunishId());//扣罚ID
                newnode.setPunishName(node.getPunishName());//扣罚方案名字
                newnode.setIsWarning(node.getIsWarning());//是否预警
                newnode.setVersion(0L);//设置版本号
                newnode.setFlag(1);
                this.saveOpt(newnode, sessionUser);
                productNodeDao.save(newnode);
            }
        }
    }
}
